import { Object3D, Scene } from "three";

import Camera from "./Cameras";
import Helper from "./Helpers";
import Renderer from "./Renderer";
import Size from "./Size";
import Time from "./Time";
import Control from "./Controls";
import Lights from "./Lights";
import EventManger from "./Events";

import Box from "../threejs/World/Box";

export default class Base {
  public static base: Base;
  public canvas: HTMLCanvasElement;
  public scene: Scene;
  public cameras: Camera;
  public size: Size;
  public time: Time;
  public renderer: Renderer;
  public control: Control;
  public helper: Helper;
  public eventManger: EventManger;
  public noTransfromControlObjs: Object3D[] = [];

  constructor(canvas: HTMLCanvasElement) {
    Base.base = this;

    this.canvas = canvas as HTMLCanvasElement;
    this.scene = new Scene();
    this.size = new Size();
    this.cameras = new Camera();
    this.time = new Time();
    this.renderer = new Renderer();
    new Lights();

    // helper
    const helper = new Helper();
    this.helper = helper;
    this.noTransfromControlObjs.push(helper.gridHelper, helper.axesHelper);

    // control
    const control = new Control();
    this.control = control;
    this.noTransfromControlObjs.push(this.control.transformControl);
    // events
    this.eventManger = new EventManger();

    // 使用EventManager实例注册的事件,就是相当于全局事件,
    this.eventManger.addEventListener("click", (e) => {
      console.log("点击射线穿过了下面这些物体");
      console.log(e);
    });

    // 添加box----------------------
    new Box();

    this.time.on("update", () => {
      this.update();
    });
    this.size.on("resize", () => {
      this.resize();
    });
  }

  public static getInstance(canvas?: HTMLCanvasElement) {
    if (canvas === undefined && Base.base !== undefined) {
      return Base.base;
    }
    Base.base = new Base(canvas as HTMLCanvasElement);
    return Base.base;
  }

  private resize() {
    this.cameras.resize();
    this.renderer.resize();
  }

  private update() {
    this.control.update();
    this.renderer.update();
  }
}

